package cn.iocoder.yudao.module.promotion.service.rankinglist;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.promotion.controller.admin.rankinglist.vo.*;
import cn.iocoder.yudao.module.promotion.controller.app.rankinglist.vo.AppRankingListDetailRespVo;
import cn.iocoder.yudao.module.promotion.controller.app.rankinglist.vo.AppRankingListUserInfoRespVo;
import cn.iocoder.yudao.module.promotion.convert.rankinglist.RankingListConvert;
import cn.iocoder.yudao.module.promotion.dal.dataobject.rankinglist.RankingListDO;
import cn.iocoder.yudao.module.promotion.dal.mysql.rankinglist.RankingListMapper;
import cn.iocoder.yudao.module.trade.api.brokerage.BrokerageRecordApi;
import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageRecordDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.RANKING_LIST_EXISTS;
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.RANKING_LIST_NOT_EXISTS;

/**
 * 活动排行榜 Service 实现类
 *
 * @author 万民匠心
 */
@Slf4j
@Service
@Validated
public class RankingListServiceImpl implements RankingListService {

    @Resource
    private RankingListMapper rankingListMapper;

    @Resource
    private MemberUserApi memberUserApi;

    @Resource
    private BrokerageRecordApi brokerageRecordApi;

    @Override
    public Long createRankingList(RankingListSaveReqVO createReqVO) {
        validateRankingListDateExists(0L, createReqVO.getStartTime(), createReqVO.getEndTime());
        // 插入
        RankingListDO rankingList = BeanUtils.toBean(createReqVO, RankingListDO.class);
        rankingList.setStatus(0);
        rankingListMapper.insert(rankingList);
        // 返回
        return rankingList.getId();
    }

    @Override
    public void updateRankingList(RankingListRespVO updateReqVO) {
        // 校验存在
        validateRankingListExists(updateReqVO.getId());
        validateRankingListDateExists(updateReqVO.getId(), updateReqVO.getStartTime(), updateReqVO.getEndTime());
        // 更新
        RankingListDO updateObj = BeanUtils.toBean(updateReqVO, RankingListDO.class);
        rankingListMapper.updateById(updateObj);
    }

    @Override
    public void deleteRankingList(Long id) {
        // 校验存在
        validateRankingListExists(id);
        // 删除
        rankingListMapper.deleteById(id);
    }

    private void validateRankingListExists(Long id) {
        if (rankingListMapper.selectById(id) == null) {
            throw exception(RANKING_LIST_NOT_EXISTS);
        }
    }

    private void validateRankingListDateExists(Long id, LocalDateTime startTime, LocalDateTime endTime) {
        RankingListDO rankingListDO = rankingListMapper.selectOne(new LambdaQueryWrapperX<RankingListDO>()
                .between(RankingListDO::getStartTime, startTime, endTime).or(w -> w.between(RankingListDO::getEndTime, startTime, endTime)));
        if (rankingListDO != null && !Objects.equals(rankingListDO.getId(), id)) {
            log.error("投放日期已有其他排行活动, {}", JSONUtil.toJsonStr(rankingListDO));
            throw exception(RANKING_LIST_EXISTS);
        }
    }

    @Override
    public RankingListDO getRankingList(Long id) {
        return rankingListMapper.selectById(id);
    }

    @Override
    public PageResult<RankingListDO> getRankingListPage(RankingListPageReqVO pageReqVO) {
        return rankingListMapper.selectPage(pageReqVO);
    }

    @Override
    public RankingListDO getRankingListNow(LocalDateTime now) {
        return rankingListMapper.selectOne(new LambdaQueryWrapperX<RankingListDO>()
                .gtIfPresent(RankingListDO::getEndTime, now)
                .ltIfPresent(RankingListDO::getStartTime, now)
        );
    }

    @Override
    public AppRankingListDetailRespVo getAppRankingListDetailById(Long id) {
        RankingListDO rankingListDO = rankingListMapper.selectById(id);
        if (null == rankingListDO) {
            throw exception(RANKING_LIST_NOT_EXISTS);
        }
        //排行榜信息
        List<BrokerageRecordDto> brokerageRecordList = brokerageRecordApi.getUserBrokerageRecordListByRankingId(rankingListDO.getId());

        //用户信息
        List<MemberUserRespDTO> memberUserList = memberUserApi.getUserList(convertSet(brokerageRecordList, BrokerageRecordDto::getUserId));
        //拼接组合


        return RankingListConvert.INSTANCE.convert(rankingListDO,brokerageRecordList,memberUserList);

    }

    @Override
    public RankingListDeatilRespVo getRankingListDetailById(Long id){
        RankingListDO rankingListDO = rankingListMapper.selectById(id);
        if (null == rankingListDO) {
            throw exception(RANKING_LIST_NOT_EXISTS);
        }
        RankingListDeatilRespVo rankingListDeatilRespVo = BeanUtils.toBean(rankingListDO,RankingListDeatilRespVo.class);
        //排行榜信息
        List<BrokerageRecordDto> brokerageRecordList = brokerageRecordApi.getUserBrokerageRecordListByRankingId(rankingListDO.getId());

        //用户信息
        List<MemberUserRespDTO> memberUserList = memberUserApi.getUserList(convertSet(brokerageRecordList, BrokerageRecordDto::getUserId));

        List<RankingListUserInfoRespVo> rankingListUserInfoRespVoList = RankingListConvert.INSTANCE.convert(brokerageRecordList,memberUserList);

        rankingListDeatilRespVo.setUserInfoRespVoList(rankingListUserInfoRespVoList);

        return rankingListDeatilRespVo;
    }



    @Override
    public AppRankingListUserInfoRespVo getMyRankingListDetailById(Long id, Long userId) {
        RankingListDO rankingListDO = rankingListMapper.selectById(id);
        if (null == rankingListDO) {
            throw exception(RANKING_LIST_NOT_EXISTS);
        }
        BrokerageRecordDto brokerageRecordDto = brokerageRecordApi.getUserBrokerageRecordListByRankingIdAndUserId(id, userId);
        if (ObjectUtil.isNull(brokerageRecordDto)) {
            return null;
        }
        MemberUserRespDTO memberUserRespDTO = memberUserApi.getUser(userId);

        return RankingListConvert.INSTANCE.convert(brokerageRecordDto, memberUserRespDTO);
    }

}